#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
条码可视化工具
将生成的二进制条码转换为可视化的条形码图像
"""

import matplotlib.pyplot as plt
import numpy as np
from barcode_generator import generate_barcode
import argparse

def visualize_barcode(barcode_str, title="条码", save_path=None, show=True):
    """
    可视化条码
    
    Args:
        barcode_str (str): 二进制条码字符串
        title (str): 图像标题
        save_path (str): 保存路径，None表示不保存
        show (bool): 是否显示图像
    """
    if not barcode_str:
        print("错误：条码字符串为空")
        return
    
    # 将字符串转换为数值数组
    bars = [int(bit) for bit in barcode_str]
    
    # 创建图像
    fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8))
    
    # 上半部分：条形码可视化
    bar_width = 1.0
    x_positions = np.arange(len(bars))
    colors = ['white' if bar == 0 else 'black' for bar in bars]
    
    ax1.bar(x_positions, [1] * len(bars), width=bar_width, 
            color=colors, edgecolor='none')
    ax1.set_xlim(-0.5, len(bars) - 0.5)
    ax1.set_ylim(0, 1)
    ax1.set_title(f'{title}\n条码内容: {barcode_str}', fontsize=12, pad=20)
    ax1.set_ylabel('条形码', fontsize=10)
    ax1.set_xticks(x_positions[::2])  # 每隔一个显示刻度
    ax1.set_xticklabels([str(i) for i in x_positions[::2]], fontsize=8)
    ax1.grid(True, alpha=0.3)
    
    # 下半部分：数字序列可视化
    ax2.plot(x_positions, bars, 'bo-', linewidth=2, markersize=4)
    ax2.fill_between(x_positions, bars, alpha=0.3)
    ax2.set_xlim(-0.5, len(bars) - 0.5)
    ax2.set_ylim(-0.1, 1.1)
    ax2.set_xlabel('位置', fontsize=10)
    ax2.set_ylabel('数值 (0/1)', fontsize=10)
    ax2.set_title('数字序列', fontsize=10)
    ax2.grid(True, alpha=0.3)
    ax2.set_xticks(x_positions)
    ax2.set_xticklabels([str(i) for i in x_positions], fontsize=8, rotation=45)
    
    # 在每个点上标注数值
    for i, val in enumerate(bars):
        ax2.annotate(str(val), (i, val), textcoords="offset points", 
                    xytext=(0,10), ha='center', fontsize=8)
    
    plt.tight_layout()
    
    # 保存图像
    if save_path:
        plt.savefig(save_path, dpi=300, bbox_inches='tight')
        print(f"条码图像已保存到: {save_path}")
    
    # 显示图像
    if show:
        plt.show()
    else:
        plt.close()

def create_ascii_barcode(barcode_str, width=2):
    """
    创建ASCII艺术条码
    
    Args:
        barcode_str (str): 二进制条码字符串
        width (int): 每个条的宽度
    
    Returns:
        str: ASCII艺术条码
    """
    if not barcode_str:
        return ""
    
    # 创建条码行
    bar_line = ""
    number_line = ""
    
    for i, bit in enumerate(barcode_str):
        if bit == '1':
            bar_line += "█" * width  # 黑色块
        else:
            bar_line += " " * width  # 空白
        
        # 数字行（每个位置显示对应的数字）
        if width == 1:
            number_line += bit
        else:
            number_line += bit + " " * (width - 1)
    
    # 创建位置行
    position_line = ""
    for i in range(len(barcode_str)):
        pos_str = str(i % 10)
        if width == 1:
            position_line += pos_str
        else:
            position_line += pos_str + " " * (width - 1)
    
    result = f"位置: {position_line}\n"
    result += f"数值: {number_line}\n"
    result += f"条码: {bar_line}\n"
    
    return result

def batch_generate_barcodes(output_dir="barcodes", image_format="png"):
    """
    批量生成所有可能的条码
    
    Args:
        output_dir (str): 输出目录
        image_format (str): 图像格式
    """
    import os
    
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    
    print(f"开始批量生成条码到目录: {output_dir}")
    
    total_count = 0
    for project_id in range(1, 81):  # 1-80
        for batch_id in range(1, 61):  # 1-60
            barcode = generate_barcode(project_id, batch_id)
            if barcode:
                filename = f"barcode_P{project_id:02d}_B{batch_id:02d}.{image_format}"
                filepath = os.path.join(output_dir, filename)
                title = f"项目{project_id} 批次{batch_id}"
                
                visualize_barcode(barcode, title=title, save_path=filepath, show=False)
                total_count += 1
                
                if total_count % 100 == 0:
                    print(f"已生成 {total_count} 个条码...")
    
    print(f"批量生成完成！总共生成了 {total_count} 个条码")

def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='条码可视化工具')
    parser.add_argument('--project', type=int, help='项目编号 (1-80)')
    parser.add_argument('--batch', type=int, help='批次 (1-60)')
    parser.add_argument('--barcode', type=str, help='直接输入条码字符串')
    parser.add_argument('--save', type=str, help='保存图像的路径')
    parser.add_argument('--ascii', action='store_true', help='显示ASCII艺术条码')
    parser.add_argument('--batch-generate', action='store_true', help='批量生成所有条码')
    parser.add_argument('--no-show', action='store_true', help='不显示图像窗口')
    
    args = parser.parse_args()
    
    if args.batch_generate:
        batch_generate_barcodes()
        return
    
    barcode_str = None
    title = "条码"
    
    if args.barcode:
        barcode_str = args.barcode
        title = f"自定义条码"
    elif args.project and args.batch:
        barcode_str = generate_barcode(args.project, args.batch)
        title = f"项目{args.project} 批次{args.batch}"
    else:
        # 交互式输入
        print("=== 条码可视化工具 ===")
        choice = input("选择输入方式:\n1. 输入项目编号和批次\n2. 直接输入条码字符串\n请选择 (1/2): ").strip()
        
        if choice == '1':
            try:
                project_id = int(input("请输入项目编号 (1-80): "))
                batch_id = int(input("请输入批次 (1-60): "))
                barcode_str = generate_barcode(project_id, batch_id)
                title = f"项目{project_id} 批次{batch_id}"
            except ValueError:
                print("错误：请输入有效的数字")
                return
        elif choice == '2':
            barcode_str = input("请输入条码字符串 (只包含0和1): ").strip()
            if not all(c in '01' for c in barcode_str):
                print("错误：条码字符串只能包含0和1")
                return
            title = "自定义条码"
        else:
            print("无效选择")
            return
    
    if not barcode_str:
        print("错误：无法生成条码")
        return
    
    print(f"\n条码字符串: {barcode_str}")
    print(f"条码长度: {len(barcode_str)}")
    
    # 显示ASCII艺术条码
    if args.ascii or input("\n是否显示ASCII艺术条码? (y/n): ").lower() == 'y':
        print("\nASCII艺术条码:")
        print(create_ascii_barcode(barcode_str))
    
    # 生成图像
    show_image = not args.no_show
    if not show_image and not args.save:
        show_image = input("是否显示图像? (y/n): ").lower() == 'y'
    
    visualize_barcode(barcode_str, title=title, save_path=args.save, show=show_image)

if __name__ == "__main__":
    main()
